package com.common.shiro;


import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.common.dto.AccountInfoDTO;
import com.common.dto.PrivilegeDTO;
import com.common.service.AccountInfoService;
import com.common.util.DESedeUtil;
import com.common.util.StringUtil;



public class SystemAuthorizingRealm extends AuthorizingRealm {
	private Logger logger = Logger.getLogger(this.getClass());
	
	/** 加密的密钥 */
	@Value("${accountKey}")
	private String accountKey;
	
	@Autowired
	private AccountInfoService accountInfoService;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		AccountInfoDTO accountDTO = (AccountInfoDTO) principals.getPrimaryPrincipal();
		List<String> permissionList = new ArrayList<String>();
		//获取权限
		List<PrivilegeDTO> listPrivilege =accountInfoService.findPrivilegesByPersonCode(accountDTO.getPersonCode());
		accountDTO.setListPrivilege(listPrivilege);
		// 添加权限
		if (listPrivilege != null) {
			for (PrivilegeDTO privilegeDTO : listPrivilege) {
				String permissionCode = privilegeDTO.getPermissionCode();
				if (!StringUtil.isBlank(permissionCode)) {
					permissionList.add(privilegeDTO.getPermissionCode());
				}
			}
		}
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.addStringPermissions(permissionList);
		return simpleAuthorizationInfo;
	}

	/**
	 * realm的认证方法，从数据库查询用户信息
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String userCode = (String) token.getPrincipal();
		//System.out.println(userCode+" get accountCode !");
		AccountInfoDTO accountPara = new AccountInfoDTO();
		accountPara.setAccountCode(userCode);
		accountPara = accountInfoService.getAccountInfo(accountPara);
		accountPara = accountInfoService.selectByKey(accountPara.getId());
//		if (accountPara == null) {
//			throw new AuthenticationException("account is not exist!");
//		}
		if ("2".equals(accountPara.getStatus())) {
			throw new AuthenticationException("locked");
		}
		String id = accountPara.getId();
		String accPwd = accountPara.getAccountPwd();
		String ivSpec = id.substring(0, 8);
		// 用户登录对密码进行jie密
		try {
			byte[] keyByte = DESedeUtil.getKeyByte(accountKey);
			accPwd = DESedeUtil.decryptMode(keyByte, DESedeUtil.hexStringToByte(accPwd), ivSpec);
			//System.out.println(accPwd+"解密后的密码");
		} catch (Exception e) {
			logger.error("decrypt fail", e);
		}
//		accountPara.setAccountPwd(null);
		// password密文，传入
		accPwd = new Md5Hash(accPwd).toHex();
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(accountPara, accPwd,this.getName());
		return simpleAuthenticationInfo;
	}

	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
}
